05.a - ntfy-Integration-&-Message-Broker
Relevant source files
Purpose & ScopeLink copied!
This document describes how godeep.wiki uses ntfy.sh as an event-driven message broker to coordinate the automation pipeline. ntfy.sh serves as the central communication hub that triggers repository cloning when customers complete both payment and GitHub connection. The system sends two types of notifications: payment confirmations from Stripe webhooks and installation confirmations from GitHub OAuth callbacks. Automation scripts subscribe to these notifications and execute the cloning pipeline.
For details on what happens after notifications are received, see Repository Cloning Automation. For the automation script implementations, see Automation Scripts.
ntfy.sh as Message BrokerLink copied!
The system uses ntfy.sh, a simple HTTP-based pub/sub notification service, as its message broker. This architectural choice eliminates the need for a database or complex message queue infrastructure. Notifications are sent via HTTP POST requests and received by scripts that subscribe using ntfy subscribe.
Why ntfy.shLink copied!
| Characteristic | Benefit |
|---|---|
| No Authentication Required | Simplifies integration; no OAuth or API keys needed for basic usage |
| HTTP-Based | Easy to send notifications from any environment (Vercel serverless functions, bash scripts) |
| Real-Time Streaming | Scripts receive notifications immediately via SSE (Server-Sent Events) |
| Zero Infrastructure | No need to manage message queues, databases, or polling mechanisms |
| Topic-Based Routing | Simple topic names enable logical separation of notification streams |
The trade-off is that ntfy.sh provides no message persistence beyond basic retention and no delivery guarantees for offline subscribers.
Sources: Overall system architecture analysis, scripts/ntfy-godeep-automation.sh L1-L151
Topic ConfigurationLink copied!
Topic NamingLink copied!
The system uses a custom topic name stored in the NTFY_TOPIC environment variable. The production topic follows this pattern:
topic-XXXXXXXX
The topic name includes:
- Namespace prefix:
klaudioz-codex-alerts(identifies the system owner) - Random suffix:
8sd7fg098sd7g2nkd(provides obscurity to prevent unauthorized subscriptions)
Environment VariablesLink copied!
| Variable | Location | Purpose | Default |
|---|---|---|---|
NTFY_TOPIC | Vercel environment | Topic name for production notifications | godeep-wiki-payments |
NTFY_TOPIC (script) | Hardcoded in script | Topic the automation script subscribes to | topic-XXXXXXXX |
Important: The NTFY_TOPIC value in the Vercel environment must match the hardcoded value in the automation scripts. If they differ, notifications will not reach the automation pipeline.
Sources: app/api/webhooks/stripe/route.ts L62
app/api/auth/github/callback/route.ts L114
scripts/ntfy-godeep-automation.sh L6
Notification ArchitectureLink copied!
Dual Notification SourcesLink copied!
Diagram: Message Flow from Notification Sources to Consumers
The system sends two notifications per customer workflow:
- Step 1: Payment Received - Triggered by Stripe webhook when
checkout.session.completedevent occurs - Step 2: GitHub Connected - Triggered by GitHub OAuth callback when installation_id is received
Only the Step 2 notification triggers automation. The Step 1 notification serves as an alert for manual correlation.
Sources: app/api/webhooks/stripe/route.ts L48-L82
app/api/auth/github/callback/route.ts L99-L138
Notification Payload StructureLink copied!
Step 1: Payment ReceivedLink copied!
Sent from app/api/webhooks/stripe/route.ts L70-L79
:
Diagram: Payment Notification Structure
| Field | Source | Example Value |
|---|---|---|
| Amount | session.amount_total / 100 | $10.00 |
| Customer | session.customer_email or session.customer_details?.email | user@example.com |
| Match ID | session.id.slice(-12) | XYZ789ABC123 |
| Time | new Date().toLocaleString('en-US', {timeZone: 'America/New_York'}) | 1/15/2024, 3:45:12 PM |
The Match ID (last 12 characters of the Stripe session_id) enables manual correlation between payment and GitHub connection events.
Sources: app/api/webhooks/stripe/route.ts L63-L79
Step 2: GitHub ConnectedLink copied!
Sent from app/api/auth/github/callback/route.ts L120-L132
:
Diagram: GitHub Connection Notification Structure
| Field | Source | Example Value |
|---|---|---|
| Installation ID | searchParams.get("installation_id") | 12345678 |
| Customer | userData.email or userData.login | user@example.com |
| Match ID | stripeSessionId.slice(-12) (from decoded state) | XYZ789ABC123 |
| Time | new Date().toLocaleString('en-US', {timeZone: 'America/New_York'}) | 1/15/2024, 3:46:30 PM |
The Installation ID is the critical piece of data that automation scripts extract to generate access tokens and clone repositories.
Sources: app/api/auth/github/callback/route.ts L113-L132
Event Correlation via Match IDLink copied!
Linking Payment to GitHub ConnectionLink copied!
Diagram: Match ID Correlation Flow
The Match ID (last 12 characters of session_id) appears in both notifications, enabling manual verification that payment and GitHub connection belong to the same customer. This is critical because:
- The system has no database to automatically link records
- The owner must verify payment before processing repositories
- Logs can be searched for the Match ID to find the corresponding Stripe session_id
Match ID Extraction:
- Payment notification: app/api/webhooks/stripe/route.ts L67 -
session.id.slice(-12) - GitHub notification: app/api/auth/github/callback/route.ts L118 -
stripeSessionId.slice(-12)
Sources: app/api/webhooks/stripe/route.ts L67-L68
app/api/auth/github/callback/route.ts L39-L118
Notification ConsumptionLink copied!
Subscription MechanismLink copied!
The automation script subscribes to ntfy using the ntfy subscribe command:
ntfy subscribe "$TOPIC" | while read -r line; do # Process each notification as JSONdone
From scripts/ntfy-godeep-automation.sh L39
JSON ParsingLink copied!
Each notification arrives as a JSON object with this structure:
{ "id": "unique_notification_id", "time": 1705345512, "event": "message", "topic": "topic-XXXXXXXX", "message": "✅ GitHub Connected!\n\n🔑 Installation ID: 12345678\n...", "title": "Step 2: GitHub Connected - GoDeep.wiki", "priority": 5, "tags": ["white_check_mark", "rocket"]}
Installation ID ExtractionLink copied!
The automation script filters notifications by title and extracts the installation_id:
Diagram: Notification Processing Logic
The extraction happens at scripts/ntfy-godeep-automation.sh L48-L53
:
if echo "$title" | grep -q "GitHub Connected\|GitHub Installation"; then # Extract Installation ID from message (macOS compatible) installation_id=$(echo "$message" | grep -o 'Installation ID: [0-9]*' | grep -o '[0-9]*$')fi
Sources: scripts/ntfy-godeep-automation.sh L39-L53
Code Entity ReferenceLink copied!
Sending NotificationsLink copied!
| Code Location | Notification Type | Trigger Event |
|---|---|---|
| app/api/webhooks/stripe/route.ts L70-L79 | Step 1: Payment Received | checkout.session.completed Stripe webhook event |
| app/api/auth/github/callback/route.ts L123-L132 | Step 2: GitHub Connected | GitHub OAuth callback with installation_id present |
Receiving NotificationsLink copied!
| Code Location | Purpose |
|---|---|
| scripts/ntfy-godeep-automation.sh L39 | Subscribe to ntfy topic using SSE stream |
| scripts/ntfy-godeep-automation.sh L41-L42 | Parse JSON fields (message, title) using jq |
| scripts/ntfy-godeep-automation.sh L49 | Filter for GitHub installation notifications |
| scripts/ntfy-godeep-automation.sh L53 | Extract installation_id using regex |
ConfigurationLink copied!
| Code Location | Configuration Item |
|---|---|
| scripts/ntfy-godeep-automation.sh L6 | Hardcoded topic: topic-XXXXXXXX |
| app/api/webhooks/stripe/route.ts L62 | Read NTFY_TOPIC from environment, fallback: godeep-wiki-payments |
| app/api/auth/github/callback/route.ts L114 | Read NTFY_TOPIC from environment, fallback: godeep-wiki-payments |
Sources: All files referenced in this section
Notification HeadersLink copied!
HTTP Headers for ntfy.sh POST RequestsLink copied!
Both notification sources use the same header pattern:
| Header | Purpose | Example Values |
|---|---|---|
Content-Type | Message format | text/plain |
Title | Notification title (displayed in apps) | "Step 1: Payment Received - GoDeep.wiki" |
Priority | Notification urgency | "high" (value: 4-5 on ntfy scale) |
Tags | Emoji tags for visual identification | Payment: "moneybag,tada"GitHub: "white_check_mark,rocket" |
The ntfy.sh service interprets these headers to format notifications in subscriber clients (mobile apps, desktop apps, web interface).
Sources: app/api/webhooks/stripe/route.ts L70-L77
app/api/auth/github/callback/route.ts L123-L130
Error HandlingLink copied!
Notification Delivery FailuresLink copied!
The system logs errors but does not retry failed notifications:
Stripe Webhook Handler app/api/webhooks/stripe/route.ts L70-L81
:
await fetch(`https://ntfy.sh/${ntfyTopic}`, { /* ... */ })console.log(`📲 Notification sent to ntfy.sh/${ntfyTopic}`)
- No try-catch around the fetch
- Errors propagate to Stripe webhook response handler
GitHub Callback Handler app/api/auth/github/callback/route.ts L122-L137
:
try { await fetch(`https://ntfy.sh/${ntfyTopic}`, { /* ... */ }) console.log(`Notification sent to ntfy.sh/${ntfyTopic}`)} catch (error) { console.error("Failed to send ntfy notification:", error)}
- Errors are caught and logged
- OAuth flow continues even if notification fails
ImplicationsLink copied!
If notification delivery fails:
- Payment notification failure: Owner receives no alert about new payment (must check Stripe dashboard manually)
- GitHub notification failure: Automation does not trigger; owner must manually process repository using admin panel
The system prioritizes user experience (completing OAuth flow) over notification reliability.
Sources: app/api/webhooks/stripe/route.ts L70-L82
app/api/auth/github/callback/route.ts L122-L138
Refresh this wiki
Last indexed: 23 November 2025 (922b35)
On this page
- ntfy Integration & Message Broker
- Purpose & Scope
- ntfy.sh as Message Broker
- Why ntfy.sh
- Topic Configuration
- Topic Naming
- Environment Variables
- Notification Architecture
- Dual Notification Sources
- Notification Payload Structure
- Step 1: Payment Received
- Step 2: GitHub Connected
- Event Correlation via Match ID
- Linking Payment to GitHub Connection
- Notification Consumption
- Subscription Mechanism
- JSON Parsing
- Installation ID Extraction
- Code Entity Reference
- Sending Notifications
- Receiving Notifications
- Configuration
- Notification Headers
- HTTP Headers for ntfy.sh POST Requests
- Error Handling
- Notification Delivery Failures
- Implications
Ask Devin about godeep.wiki-jb
Syntax error in text
mermaid version 11.4.1